package cn.tedu.ivosback.audit.service.impl;

import cn.tedu.ivosback.application.mapper.ApplicationMapper;
import cn.tedu.ivosback.application.pojo.entity.Application;
import cn.tedu.ivosback.audit.mapper.AuditMapper;
import cn.tedu.ivosback.audit.pojo.dto.AuditParam;
import cn.tedu.ivosback.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivosback.audit.pojo.entity.Audit;
import cn.tedu.ivosback.audit.pojo.vo.AuditVO;
import cn.tedu.ivosback.audit.service.AuditService;
import cn.tedu.ivosback.base.enums.ApplicationStatusEnum;
import cn.tedu.ivosback.base.enums.AuditStatusEnum;
import cn.tedu.ivosback.user.pojo.vo.UserVO;
import cn.tedu.ivosback.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
@Slf4j
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserService userService;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("生成申请单对应的审批数据:application={}", application);
        List<Long> auditUserIdList = application.getAuditUserIdList();
        for (int i = 0; i < auditUserIdList.size(); i++) {
            Audit audit = new Audit();
            audit.setApplicationId(application.getId());
            audit.setAuditUserId(auditUserIdList.get(i));
            audit.setAuditSort(i);
            if (i == 0) {
                // 0表示第1条审批数据,对应的人是直属领导,审批状态为"待我审核"
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            } else {
                // 1表示第2条审批数据,对应的人是上上级,审批状态为"待他人审核"
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            audit.setCreateTime(new Date());
            auditMapper.insertAudit(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long applicationId) {
        log.debug("根据申请单id查询审批数据:applicationId={}", applicationId);
        return auditMapper.selectAuditByApplicationId(applicationId);
    }

    @Override
    public void deleteAuditByApplicationId(Long applicationId) {
        log.debug("根据申请单id删除审批数据:applicationId={}", applicationId);
        auditMapper.deleteByApplicationId(applicationId);
    }

    @Override
    public List<AuditVO> selectAudit(AuditParam auditParam) {
        log.debug("查询审批单的业务:auditQuery={}", auditParam);
        List<AuditVO> list = auditMapper.selectAudit(auditParam);
        for (int i = 0; i < list.size(); i++) {
            AuditVO auditVO = list.get(i);
            assignAuditUserList(auditVO);
        }
        return list;
    }

    public void assignAuditUserList(AuditVO auditVO) {
        List<String> auditUsernameList = new ArrayList<>();
        List<AuditVO> auditVOList = auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        for (int i = 0; i < auditVOList.size(); i++) {
            UserVO userVO = userService.selectById(auditVOList.get(i).getAuditUserId());
            auditUsernameList.add(userVO.getUsername());
        }
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String auditUsername : auditUsernameList) {
            stringJoiner.add(auditUsername);
        }
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批数据:audit={}", auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam, audit);
        audit.setUpdateTime(new Date());
        auditMapper.updateAudit(audit);
        log.debug("更新内容");
        Application application = new Application();
        application.setId(auditSaveParam.getApplicationId());
        application.setUpdateTime(new Date());
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())) {
            AuditParam auditParam = new AuditParam();
            auditParam.setApplicationId(audit.getApplicationId());
            Integer count = auditMapper.selectRestAuditCount(auditParam);
            if (count > 0) {
                auditParam.setAuditSort(audit.getAuditSort() + 1);
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditParam);
                if (auditVOList.size() > 0 && auditVOList != null) {
                    AuditVO auditVO = auditVOList.get(0);
                    Audit audit1 = new Audit();
                    audit1.setId(auditVO.getId());
                    audit1.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    audit1.setUpdateTime(new Date());
                    auditMapper.updateAudit(audit1);
                }
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.updateApplication(application);
            } else {
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.updateApplication(application);
            }
        } else if (audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())) {
            AuditParam auditParam = new AuditParam();
            auditParam.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditParam);
            if (auditVOList != null && auditVOList.size() > 0) {
                for (int i = 0; i < auditVOList.size(); i++) {
                    AuditVO auditVO = auditVOList.get(i);
                    if (auditVO.getAuditStatus().equals(AuditStatusEnum.PENDING.getCode())) {
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.updateApplication(application);
        }
    }
}